#include "D3DRender.h"

D3DRender::D3DRender()
{
	Init();
}

D3DRender::~D3DRender(void)
{
	device->ClearState();

	ReleaseCOM(renderTargetView);
	ReleaseCOM(depthStencilBuffer);
	ReleaseCOM(depthStencilView);
	ReleaseCOM(swapChain);
	ReleaseCOM(device);
}


void D3DRender::Init()
{
	DXGI_SWAP_CHAIN_DESC sd;
	sd.BufferDesc.Width = GD::_ED.windowWidth;
	sd.BufferDesc.Height = GD::_ED.windowHeight;
	sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
	sd.BufferDesc.RefreshRate.Numerator = 60;
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;

	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;

	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.BufferCount = 1;
	sd.OutputWindow = GD::_ED.hWnd;
	sd.Windowed = GD::_ED.windowed;
	sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
	sd.Flags = 0;

	UINT createDeviceFlags = D3D10_CREATE_DEVICE_BGRA_SUPPORT;
#if defined(DEBUG) || defined(_DEBUG)
	createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
#endif

	HR(D3D10CreateDeviceAndSwapChain1(NULL, D3D10_DRIVER_TYPE_HARDWARE, 0, createDeviceFlags, D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &sd, &swapChain, &device));

	ID3D10Texture2D* backBuffer;
	swapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), reinterpret_cast<void**>(&backBuffer));
	device->CreateRenderTargetView(backBuffer, 0, &renderTargetView);
	ReleaseCOM(backBuffer);

	D3D10_TEXTURE2D_DESC dsDesc;
	dsDesc.Width = GD::_ED.windowWidth;
	dsDesc.Height = GD::_ED.windowHeight;
	dsDesc.MipLevels = 1;
	dsDesc.ArraySize = 1;
	dsDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
	dsDesc.SampleDesc.Count = 1;
	dsDesc.SampleDesc.Quality = 0;
	dsDesc.Usage = D3D10_USAGE_DEFAULT;
	dsDesc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
	dsDesc.CPUAccessFlags = 0;
	dsDesc.MiscFlags = 0;

	HR(device->CreateTexture2D(&dsDesc, 0, &depthStencilBuffer));
	HR(device->CreateDepthStencilView(depthStencilBuffer, 0, &depthStencilView));

	device->OMSetRenderTargets(1, &renderTargetView, depthStencilView);

	D3D10_VIEWPORT vp;
	vp.Width = GD::_ED.windowWidth;
	vp.Height = GD::_ED.windowHeight;
	vp.TopLeftX = 0;
	vp.TopLeftY = 0;
	vp.MinDepth = 0.0f;
	vp.MaxDepth = 1.0f;

	device->RSSetViewports(1, &vp);

	D3DXMatrixPerspectiveFovLH(&projectionMatrix, (float)D3DX_PI / 0.24f, (float)GD::_ED.windowWidth / (float)GD::_ED.windowHeight, 0.1f, 1000.0f);
}

void D3DRender::Update()
{

}

void D3DRender::Draw()
{
	device->ClearRenderTargetView(renderTargetView, YELLOW);
	device->ClearDepthStencilView(depthStencilView, D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL, 1.0f, 0);

	device->OMSetDepthStencilState(0, 0);
	float blendFactors[] = {0.0f, 0.0f, 0.0f, 0.0f};
	device->OMSetBlendState(0, blendFactors, 0xffffffff);
}

void D3DRender::ReleaseResizedResources()
{
	if(device != NULL)
	{
		ReleaseCOM(renderTargetView);
		ReleaseCOM(depthStencilBuffer);
		ReleaseCOM(depthStencilView);
	}
}

void D3DRender::OnResize()
{
	if(device != NULL)
	{
		ID3D10RenderTargetView * viewList[1] = {NULL};
		device->OMSetRenderTargets(1, viewList, NULL);

		ReleaseResizedResources();

		HR(swapChain->ResizeBuffers(1, GD::_ED.windowWidth, GD::_ED.windowHeight, DXGI_FORMAT_B8G8R8A8_UNORM, 0));

		ID3D10Texture2D* backBuffer;
		swapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), reinterpret_cast<void**>(&backBuffer));
		device->CreateRenderTargetView(backBuffer, 0, &renderTargetView);
		ReleaseCOM(backBuffer);

		D3D10_TEXTURE2D_DESC dsDesc;
		dsDesc.Width = GD::_ED.windowWidth;
		dsDesc.Height = GD::_ED.windowHeight;
		dsDesc.MipLevels = 1;
		dsDesc.ArraySize = 1;
		dsDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
		dsDesc.SampleDesc.Count = 1;
		dsDesc.SampleDesc.Quality = 0;
		dsDesc.Usage = D3D10_USAGE_DEFAULT;
		dsDesc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
		dsDesc.CPUAccessFlags = 0;
		dsDesc.MiscFlags = 0;

		HR(device->CreateTexture2D(&dsDesc, 0, &depthStencilBuffer));
		HR(device->CreateDepthStencilView(depthStencilBuffer, 0, &depthStencilView));

		device->OMSetRenderTargets(1, &renderTargetView, depthStencilView);

		D3D10_VIEWPORT vp;
		vp.Width = GD::_ED.windowWidth;
		vp.Height = GD::_ED.windowHeight;
		vp.TopLeftX = 0;
		vp.TopLeftY = 0;
		vp.MinDepth = 0.0f;
		vp.MaxDepth = 1.0f;

		device->RSSetViewports(1, &vp);

		D3DXMatrixPerspectiveFovLH(&projectionMatrix, (float)D3DX_PI / 0.24f, (float)GD::_ED.windowWidth / (float)GD::_ED.windowHeight, 0.1f, 1000.0f);
	}
}